package com.jxpanda.spring.launcher;

import com.jxpanda.spring.module.auth.core.authentication.manager.CollaborativeReactiveAuthenticationManager;
import com.jxpanda.spring.module.auth.core.authentication.manager.CollaborativeReactiveAuthenticationManagerFactory;
import com.jxpanda.spring.module.auth.core.authentication.manager.OAuth2UserDetailsRepositoryReactiveAuthenticationManager;
import com.jxpanda.spring.module.auth.core.authentication.manager.WechatMiniProgramReactiveAuthenticationManager;
import com.jxpanda.spring.module.auth.core.user.OAuth2ReactiveUserDetailsRepository;
import com.jxpanda.spring.module.auth.core.user.OAuth2UserContext;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.reactive.config.EnableWebFlux;
import reactor.core.publisher.Mono;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
 * @author Panda
 */
@Configuration
@EnableAsync
@EnableWebFlux
@SpringBootApplication
public class LauncherApplication {

    @Bean
    public OAuth2ReactiveUserDetailsRepository oAuth2ReactiveUserDetailsRepository() {
        Map<String, User> userMap = new HashMap<>();
        List<SimpleGrantedAuthority> authorities = Stream.of("ROOT")
                .map(SimpleGrantedAuthority::new)
                .toList();
        Supplier<User> userSupplier = () -> new User("admin", "{noop}123456", true, true, true, true, authorities);
        return new OAuth2ReactiveUserDetailsRepository() {

            @Override
            public Mono<UserDetails> saveUser(OAuth2UserContext oAuth2UserContext) {
                User user = new User("admin", "{noop}123456", true, true, true, true, authorities);
                userMap.put(oAuth2UserContext.getOauth2UserId(), user);
                return Mono.just(user);
            }

            @Override
            public Mono<UserDetails> loadUser(OAuth2UserContext oAuth2UserContext) {
                User user = userMap.get(oAuth2UserContext.getOauth2UserId());
                if (user != null) {
                    return Mono.just(user);
                }
                return Mono.empty();
            }



            @Override
            public Mono<UserDetails> findByUsername(String username) {
                return Mono.just(userSupplier.get());
            }
        };
    }



    public static void main(String[] args) {
        SpringApplication.run(LauncherApplication.class, args);
    }

}
